﻿using System;
using System.IdentityModel.Tokens;
using System.Xml;
using Microsoft.IdentityModel.Claims;
using Microsoft.IdentityModel.Tokens;

namespace Microsoft.IdentityModel.OAuth
{
    //Enables callback based UserName/Password validation - Similar to WCF UserNamePasswordValidator.
    public class CustomUserNameSecurityTokenHandler : UserNameSecurityTokenHandler
    {
        public Action<string, string> UserNamePasswordValidator { get; set; }
        public CustomUserNameSecurityTokenHandler()
        {
            base.RetainPassword = true;
        }
        public override bool CanValidateToken
        {
            get
            {
                return true;
            }
        }
        public override ClaimsIdentityCollection ValidateToken(SecurityToken token)
        {
            var userNameToken = token as UserNameSecurityToken;
            if (userNameToken == null)
                throw new ArgumentException("Invalid token argument.");

            if (this.UserNamePasswordValidator == null)
            {
                throw new InvalidOperationException("Custom validator is missing. " +
                    "Please specify your custom validator using the UserNamePasswordValidator property of CustomUserNameSecurityTokenHandler");
            }

            this.UserNamePasswordValidator(userNameToken.UserName, userNameToken.Password);

            IClaimsIdentity identity = new ClaimsIdentity(
                new Claim[] 
            { 
                new Claim(ClaimTypes.Name, userNameToken.UserName)
            }, AuthenticationTypes.Password)
            {
                Claims = 
                { 
                    new Claim(ClaimTypes.AuthenticationInstant, 
                        XmlConvert.ToString(DateTime.UtcNow, "yyyy-MM-ddTHH:mm:ss.fffZ"), ClaimValueTypes.Datetime), 
                        new Claim(ClaimTypes.AuthenticationMethod, 
                            AuthenticationMethods.Password) 
                }
            };
            if (base.Configuration.SaveBootstrapTokens)
            {
                if (this.RetainPassword)
                {
                    identity.BootstrapToken = userNameToken;
                }
                else
                {
                    identity.BootstrapToken = new UserNameSecurityToken(userNameToken.UserName, null);
                }
            }
            return new ClaimsIdentityCollection(new IClaimsIdentity[] { identity });
        }

    }
}
